/*************************************************************************
*
*	gui_common.c
*
*  Copyright 2005,2006,2007,2008,2009 Steve Stancliff
*
*  Part of the TAOSF SSA system.
*
*  This module provides common GUI functions used by both
*    platform_gui and controller.
*  
*
**************************************************************************
*
*  version 1.0.5, 5/22/09, SBS
*    - add gps track to engineering tab
*
*  version 1.0.4, 5/6/09, SBS
*    - eliminate hard coded filenames in platform_gui
*
*  version 1.0.3, 5/1/09, SBS
*    - add DEFAULT_BRIGHTNESS constant
*
*  version 1.0.2, 4/26/09, SBS
*    - return handle to notebook in make_notebook()
*
*  version 1.0.1, 4/26/09, SBS
*    - add ACPI handling for laptops
*
*  version 1.0	2/27/09
*    - broken out from platform_gui.c
*
**************************************************************************
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but 
*  WITHOUT ANY WARRANTY; without even the implied warranty of 
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License 
*  along with this program; if not, write to the Free Software Foundation, 
*  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 
*
**************************************************************************/
/**
*  @file 
*  @ingroup common
*  @brief
*  This module provides common GUI functions used by both
*    platform_gui and controller.
*  <hr>
**/

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gtk/gtk.h>

#include <time.h>
#include <sys/timeb.h>

#include "config.h"
#include "waypoints.h"
#include "platform_modes.h"
#include "platform_types.h"

#define NEED_SCINAMES
#define NEED_ENGNAMES
#include "status.h"
#undef NEED_ENGNAMES
#undef NEED_SCINAMES

#include "telemfile.h"
#include "logfile.h"

#include "command.h"
#include "commandfile.h"

#include "gui_utility.h"
#include "gui_common.h"

#ifdef CONTROLLER
#include "../controller_gui/controller_gui.h"
#endif

//****************************************************************

//#define TELEMFILESPEC "data/telemetry4.txt"
//#define CMDFILESPEC "data/command4.txt"

#if defined(__armel__)||defined(__arm__)
#define TEXTFONT "Monospace 10"
#endif

#if defined(__x86_64__)
#define TEXTFONT "Monospace 8"
#endif

#define PLATFORMSTART "cd /home/steve/code/ssa/platform; ./platform > /dev/null &"
#define PLATFORMKILL  "killall -9 platform"

#define REBOOTCMD "/home/steve/bin/reboot"
#define SHUTDOWNCMD "/home/steve/bin/shutdown -h now"

#define SETTIMECMD	"ntpdate navobs1.gatech.edu"

#define CELLMODEMDIALCMD	"/usr/bin/pon &"
#define CELLMODEMHANGUPCMD	"/usr/bin/poff &"

#define USBNETROUTECMD	"/home/steve/bin/route add default gw zaphod"
#define USBNETUNROUTECMD	"/home/steve/bin/route del default gw zaphod"

#define WLANSETHOMEESSIDCMD	"/home/steve/bin/iwconfig wlan0 essid linkfoo"
#define WLANSETCMUESSIDCMD	"/home/steve/bin/iwconfig wlan0 essid CMU"
#define WLANPUMPCMD "/home/steve/bin/pump -i wlan0"

#define SUBTEXTLEN 192

#define DEFAULT_BRIGHTNESS 230


#ifdef PLAT_GUI
static char telemfilespec[64];
static char cmdfilespec[64];
#endif


//****************************************************************
//typedef struct
//{
//	GtkWidget *EngText[2];
//	GtkWidget *SciText[2];
//	GtkWidget *CmdText;
//}TXTHNDL;	


/***********************************************************
*
*	delete_event()
*/
/** 
*
* @brief
*  Called when window receives a delete event.
*
*  Returning FALSE means "go ahead and delete it"
*
*  Parameters: not used
*
***********************************************************/
gint delete_event( GtkWidget *widget, GdkEvent  *event,
                   gpointer   data )
{
    return(FALSE);
}


/***********************************************************
*
*	destroy()
*/
/** 
*
* @brief
*  Called when window receives a destroy event.
*
*  Calls gtk_main_quit to end main loop
*
*  Parameters: not used
*
***********************************************************/
void destroy( GtkWidget *widget, gpointer   data )
{
    gtk_main_quit();
	 return;
}


/******************************************************************************
*
*  SetEngSubtext()
*/
/** 
*
* @brief
*
****************************************************************/
static void SetEngSubtext(
		char *text
		,ENG_DBL s
		,char *label)
{
	snprintf(text,SUBTEXTLEN,
			"%17s : %6.3f (%s)\n"
			, label
			, s.dValue
			, s.sUnits
			);

	return;
}


/******************************************************************************
*
*  setEngineeringText()
*/
/** 
*
* @brief
*
*
****************************************************************/
static void setEngineeringText(
		STATUS s
		,TXTHNDL *th)
{
	// first tab
	{
	char temp[2048];
	struct timeb tim;
	int time,delay;

	ftime(&tim);  //get current time
	time = (int)(tim.time); // in second since 1/1/70
	delay = time - s.nTime;
	
	snprintf(temp,2048,
	
	"Platform          : %s\n"
	"Platform ID       : %d\n"
	"nPlatformType     : %d\n"
	"sPlatformTypeName : %s\n"
	"nPlatformMode     : %d\n"
	"sPlatformModeName : %s\n"
	"sTime             : %s\n"
	"nTime             : %d\n"
	"nCommsLatency     : %d\n"
	"nWaypointCount    : %d\n"
	"nCurrWaypt        : %d\n"
	"dLatDeg           : %f\n"
	"dLonDeg           : %f\n"
	"dAltMeters        : %.2f\n"
	"dSpeed_mps        : %.2f\n"
	"dWaterspeed_mps   : %.2f\n"
	"dHdgDeg           : %.2f\n"
	"dPitchDeg         : %.2f\n"
	"dRollDeg          : %.2f\n"
//	"dBattV            : %.2f\n"	
	"\n"
	"gpsdata.track     : %.2f\n"
	"\n"
	"Comms Delay (s)   : %d\n"
	"\n"
	
	, s.sPlatformName
	, s.nPlatformID
	, s.nPlatformType
	, s.sPlatformTypeName
	, s.nPlatformMode
	, s.sPlatformModeName
	, s.sTime
	, s.nTime
	, s.nCommsLatency
	, s.nWaypointCount
	, s.nCurrWaypt
	, s.dLatDeg
	, s.dLonDeg
	, s.dAltMeters
	, s.dSpeed_mps
	, s.dWaterspeed_mps
	, s.dHdgDeg
	, s.dPitchDeg
	, s.dRollDeg
//	, s.dBattVolts
	, s.gpsdata.track
	, delay
	
	);

//	printf("strlen is %d\n",strlen(temp));
	gtk_label_set_text((GtkLabel *)(th->EngText[0]),temp);
	}

	// second tab
	{
	char subtext[NUMENGDAT][SUBTEXTLEN];
	
	SetEngSubtext(subtext[0],s.dMainBattery_V
			,engdatnames[ENGDAT_MAINBATTERY]);
	SetEngSubtext(subtext[1],s.dRudderCommand
			,engdatnames[ENGDAT_RUDDER]);
	SetEngSubtext(subtext[2],s.dThrottleCommand
			,engdatnames[ENGDAT_THROTTLE]);

		{	
		int size;
		register int i;
	
		size = 0;
		for(i=0;i<NUMENGDAT;i++){
			size += strlen(subtext[i]);
		}


		{
			char temp[size+1];
			
			sprintf(temp,"%s","");
	
			for(i=0;i<NUMENGDAT;i++){
				strcat(temp,subtext[i]);
			}

			gtk_label_set_text((GtkLabel *)(th->EngText[1]),temp);
		}
		}

	}

	return;
}


/****************************************************************
*
*  setCommandText()
*/
/** 
*
* @brief
*
*
*
*
****************************************************************/
#ifdef PLAT_GUI
static void setCommandText(
		COMMAND cmd
		,GtkWidget *text)
{
	char temp[2048];
	WAYPT wp0,wp1;
	

	if(cmd.nWaypointCount > 1){
		wp0 = cmd.Waypoints[0];
		wp1 = cmd.Waypoints[1];
	}else if(cmd.nWaypointCount == 1){
		wp0 = cmd.Waypoints[0];
		wp1 = cmd.Waypoints[0];
	}else{
		wp0 = waypoints_WaypointInit();
		wp0 = waypoints_WaypointInit();
	}

	snprintf(temp,sizeof(temp),
	
		"Platform        : %s\n"
		"Platform ID     : %d\n"
		"Command         : %s\n"
		"Command ID      : %d\n"
		"\n"
		"Rudder          : %d\n"
		"Throttle        : %d\n"
		"Heading         : %d\n"
		"\n"
		"Waypoint Count  : %d\n"
		"\n"
		"Waypoint 0 : Lat = %7.4f\n"
		"           : Lon = %7.4f\n"
		"           : speed = %.2f\n"
		"           : radius = %.2f\n"
		"\n"
		"Waypoint 1 : Lat = %7.4f\n"
		"           : Lon = %7.4f\n"
		"           : speed = %.2f\n"
		"           : radius = %.2f\n"
		"\n"

		, cmd.sPlatformName
		, cmd.nPlatformID
		, cmd.sCmdName
		, cmd.nCmdID
		, cmd.nRudder
		, cmd.nThrottle
		, cmd.nHeading
		, cmd.nWaypointCount
		, wp0.dLatDeg
		, wp0.dLonDeg
		, wp0.dSpeedMps
		, wp0.dCloseEnoughM
		, wp1.dLatDeg
		, wp1.dLonDeg
		, wp1.dSpeedMps
		, wp1.dCloseEnoughM
		);
		
		
//	WAYPT Waypoints[MAXWAYPOINTS];

//	printf("strlen is %d\n",strlen(temp));
	gtk_label_set_text((GtkLabel *)(text),temp);
	
	return;
}
#endif


/****************************************************************
*
*  SetSciSubtext()
*/
/** 
*
* @brief
****************************************************************/
static void SetSciSubtext(
		char *text
		,SCI_DBL s
		,char *label)
{
	snprintf(text,SUBTEXTLEN,
			"%s\n"
			"             Value    : %6.3f (%s)\n"
			"             Time     : %s (%d)\n"
//			"             Position : (%8.5f, %8.5f)\n"
			, label
			, s.dValue
			, s.sUnits
			, s.sTime
			, s.nTime
//			, s.position.dLatDeg
//			, s.position.dLonDeg
			);

	return;
}


/****************************************************************
*
*  setScienceText()
*/
/** 
*
* @brief
*
*
****************************************************************/
static void setScienceText(
		STATUS s
		,TXTHNDL *th)
{
	char subtext[NUMSCIDAT][SUBTEXTLEN];
	register int i;
	int size;

	SetSciSubtext(subtext[0],s.dAirPress_mbar
			,scidatnames[SCIDAT_AIRPRESSURE]);
	SetSciSubtext(subtext[1],s.dAirTempDegC
			,scidatnames[SCIDAT_AIRTEMP]);
	SetSciSubtext(subtext[2],s.dHumidPct
			,scidatnames[SCIDAT_HUMIDITY]);
	SetSciSubtext(subtext[3],s.dWaterTempDegC
			,scidatnames[SCIDAT_WATERTEMP]);
	SetSciSubtext(subtext[4],s.dWindSpeed_mps
			,scidatnames[SCIDAT_WINDSPEED]);
	SetSciSubtext(subtext[5],s.dWindAngleDeg
			,scidatnames[SCIDAT_WINDANGLE]);
	SetSciSubtext(subtext[6],s.dCurrentSpeedMPS
			,scidatnames[SCIDAT_CURRENTSPEED]);
	SetSciSubtext(subtext[7],s.dCurrentAngleDeg
			,scidatnames[SCIDAT_CURRENTANGLE]);
	SetSciSubtext(subtext[8],s.dSalinity_psu
			,scidatnames[SCIDAT_SALINITY]);
	SetSciSubtext(subtext[9],s.dFluorescence_V
			,scidatnames[SCIDAT_FLUORESCENCE]);
//	SetSciSubtext(subtext[10],s.dBathymetry
//			,scidatnames[SCIDAT_BATHYMETRY]);
		
	{	
		size = 0;
		for(i=0;i<5;i++){
			size += strlen(subtext[i]);
		}


		{
			char temp[size+1];
//			register int j;
	
//			j=0;
			sprintf(temp,"%s","");
	
			for(i=0;i<5;i++){
				strcat(temp,subtext[i]);
//				strcpy(temp+j,subtext[i]);
//				j += strlen(subtext[i]);
			}

			gtk_label_set_text(GTK_LABEL(th->SciText[0]),temp);
		}
	}
	{	
		size = 0;
		for(i=5;i<10;i++){
			size += strlen(subtext[i]);
		}


		{
			char temp[size+1];
//			register int j;
	
//			j=0;
			sprintf(temp,"%s","");
	
			for(i=5;i<10;i++){
				strcat(temp,subtext[i]);
//				strcpy(temp+j,subtext[i]);
//				j += strlen(subtext[i]);
			}

			gtk_label_set_text(GTK_LABEL(th->SciText[1]),temp);
		}
	}
	
	return;
}


/****************************************************************
*
*  callback_backlight_toggle()
*/
/** 
*
* @brief
*
*
****************************************************************/
int callback_backlight_toggle(
		GtkWidget *widget
		, GtkWidget *spin )
{
	static int state=0;

	if(state==0){
		system("echo 0 >/sys/class/backlight/nomad-bl/brightness");
		state=1;
	}else{
		int value;
		char temp[128];
	
		value = gtk_spin_button_get_value((GtkSpinButton *)spin);	
		snprintf(temp,128,"echo %d >/sys/class/backlight/nomad-bl/brightness",value);
		system(temp);
		state=0;
	}

	return(TRUE);
}


/****************************************************************
*
*  callback_backlight_blink()
*/
/** 
*
* @brief
*
*
****************************************************************/
#ifdef PLAT_GUI
int callback_backlight_blink(
		GtkWidget *widget
		, GtkWidget *window )
{
	static int state=0;

	if(state==0){
		system("echo 0 >/sys/class/backlight/nomad-bl/brightness");
		state=1;
	}else{
		system("echo 255 >/sys/class/backlight/nomad-bl/brightness");
		state=0;
	}

	return(TRUE);;
}


/****************************************************************
*
*  callback_backlight_blinktoggle()
*/
/** 
*
* @brief
*
*
****************************************************************/
int callback_backlight_blinktoggle(
		GtkWidget *widget
		, GtkWidget *spin )
{
	static int state = 0;
	static int timer;

	if(state==0){

		timer = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,1
				,(GSourceFunc)callback_backlight_blink,NULL,NULL);

//		system("echo 0 >/sys/class/backlight/nomad-bl/brightness");

		state = 1;
		
	}else{
		int value;
		char temp[128];
	
		g_source_remove(timer);

		value = gtk_spin_button_get_value((GtkSpinButton *)spin);	
		snprintf(temp,128
				,"echo %d >/sys/class/backlight/nomad-bl/brightness"
				,value);
		system(temp);

		state = 0;
	}

	return(TRUE);
}
#endif


/******************************************************************************
*
*  callback_telem_remotefile()
*/
/** 
*
* @brief
*
*
****************************************************************/
#ifdef CONTROLLER
int callback_telem_remotefile(
		TXTHNDL *th)
{
	STATUS s;

	s = telemfile_GetStatus();
	
	setEngineeringText(s,th);
	
	setScienceText(s,th);

	return(TRUE);
}
#endif


/****************************************************************
*
*  callback_telem_cmd_files()
*/
/** 
*
* @brief
*
*
****************************************************************/
#ifdef PLAT_GUI
int callback_telem_cmd_localfiles(
		TXTHNDL *th)
{
	STATUS s;
	COMMAND cmd;
	register int i;
	
	i = 0;
	do{
		// if read is bogus, try again two more times
		// (read will be bogus when either (1) file is
		// currently being written or (2) telemetry
		// server reading code had a problem
		s = telemfile_ReadFile(telemfilespec);
		i++;
	}while((s.nPlatformID==-255) && (i<3));

	if(s.nPlatformID != -255){
		setEngineeringText(s,th);
	
		setScienceText(s,th);
	}

	i = 0;	
	do{
		// if read is bogus, try again two more times
		cmd = commandfile_ParseCommandFile(cmdfilespec);
		i++;
	}while((cmd.nCmdID==-255) && (i<3));
	
	if(cmd.nCmdID != -255){
		setCommandText(cmd,th->CmdText);
	}
	
	return(TRUE);
}
#endif


/****************************************************************
*
*  callback_platform_kill()
*/
/** 
*
* @brief
*
*
****************************************************************/
#ifdef PLAT_GUI
void callback_platform_kill(
		GtkWidget *widget
		, gpointer data )
{
	system(PLATFORMKILL);

	return;
}


/****************************************************************
*
*  callback_platform_start()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_platform_start(
		GtkWidget *widget
		, gpointer data )
{
	system(PLATFORMSTART);

	return;
}


/****************************************************************
*
*  callback_platformtext()
*/
/** 
*
* @brief
*
*
****************************************************************/
int callback_platformtext(
		GtkWidget *text )
{
	char temp[128],*b;
	FILE *fp;

	system("ps ax|grep platform|grep -v gui|"
			"grep -v grep|grep -v nedit > /tmp/platform.foo");

	fp = fopen("/tmp/platform.foo","r");
	if(fp == NULL){
		gtk_label_set_text(GTK_LABEL(text)
				,"Platform Status:\n  Offline");
	}else{
		fgets(temp,128,fp);
		fclose(fp);
		temp[127]='\0';

		b = strchr(temp,'p');
		if(b==NULL){
			gtk_label_set_text(GTK_LABEL(text)
					,"Platform Status:\n  Offline");
		}else{
			gtk_label_set_text(GTK_LABEL(text)
					,"Platform Status:\n  Online");
		}
	}

	return(TRUE);
}
#endif

/****************************************************************
*
*  callback_shutdown()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_shutdown(
		GtkWidget *widget
		, gpointer data )
{
	if(guiutil_DialogConfirm(
				"Are you sure you want to shutdown?"
				,"Shutdown?") !=  GTK_RESPONSE_NO){
		system(SHUTDOWNCMD);
	}	

	return;
}


/****************************************************************
*
*  callback_reboot()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_reboot(
		GtkWidget *widget
		, gpointer data )
{
	if(guiutil_DialogConfirm(
				"Are you sure you want to reboot?"
				,"Reboot?") !=  GTK_RESPONSE_NO){
		system(REBOOTCMD);
	}
	
	return;
}


/****************************************************************
*
*  callback_settime()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_settime(
		GtkWidget *widget
		, gpointer data )
{
	system(SETTIMECMD);

	return;
}


/****************************************************************
*
*  callback_wlan_pump()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_wlan_pump(
		GtkWidget *widget
		, gpointer data )
{
	system(WLANPUMPCMD);

	return;
}


/****************************************************************
*
*  callback_wlan_setcmuessid()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_wlan_setcmuessid(
		GtkWidget *widget
		, gpointer data )
{
	system(WLANSETCMUESSIDCMD);

	return;
}


/****************************************************************
*
*  callback_wlan_sethomeessid()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_wlan_sethomeessid(
		GtkWidget *widget
		, gpointer data )
{
	system(WLANSETHOMEESSIDCMD);

	return;
}


/****************************************************************
*
*  callback_usbnet_route()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_usbnet_route(
		GtkWidget *widget
		, gpointer data )
{
	system(USBNETROUTECMD);

	return;
}


/****************************************************************
*
*  callback_usbnet_unroute()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_usbnet_unroute(
		GtkWidget *widget
		, gpointer data )
{
	system(USBNETUNROUTECMD);

	return;
}


/****************************************************************
*
*  callback_cellmodem_dial()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_cellmodem_dial(
		GtkWidget *widget
		, gpointer data )
{
	system(CELLMODEMDIALCMD);

	return;
}


/****************************************************************
*
*  callback_hangup()
*/
/** 
*
* @brief
*
*
****************************************************************/
void callback_cellmodem_hangup(
		GtkWidget *widget
		, gpointer data )
{
	system(CELLMODEMHANGUPCMD);

	return;
}


/****************************************************************
*
*  callback_pppstatustext()
*/
/** 
*
* @brief
*
****************************************************************/
int callback_pppstatustext(GtkWidget *text )
{
	int i;
	
	i =system("grep ppp /proc/net/dev >/dev/null");
	if(i>0){
		gtk_label_set_text(GTK_LABEL(text),"Modem Status:\n  Offline");
	}else{
		gtk_label_set_text(GTK_LABEL(text),"Modem Status:\n  Online");
	}

	return(TRUE);
}


/****************************************************************
*
*  callback_status()
*/
/** 
*
* @brief
*
****************************************************************/
int callback_status(
			GtkWidget *text )
{
	char memory[128],load0[128],power[128];
	char net1[128],net2[128],net3[128];
	char temp[512];
	FILE *fp;
	int i;
	
	
	sprintf(memory,"  \n");
	sprintf(load0,"  \n");
	sprintf(power,"  \n");
	sprintf(net1,"  \n");
	sprintf(net2,"  \n");
	sprintf(net3,"  \n");
	
	
	// power

	#if defined(__armel__)||defined(__arm__)
	system("apm > /tmp/apm.foo");
	fp = fopen("/tmp/apm.foo","r");
	if(fp == NULL){
		snprintf(power,128,"Power status unavailable\n");
	}else{
		char temp1[128],*a;
		
		if(fgets(temp1,128,fp) == NULL){
			fclose(fp);
			snprintf(power,128,"Power status unavailable\n");
		}else{
			fclose(fp);
			temp1[127]='\0';

			a = strchr(temp1,'y');
			*(a+1) = '\0';
			a = strchr(a+2,':');
		
			snprintf(power,128,"Power o%s%s",temp1+1,a);
		}
		
	}
	#else
	system("acpi > /tmp/acpi.foo");
	fp = fopen("/tmp/acpi.foo","r");
	
	if(fp == NULL){
		snprintf(power,128,"Power status unavailable\n");
	}else{
		char temp1[128],*a;
		
		*power = '\0';
		while(fgets(temp1,128,fp) != NULL){
			a = strchr(temp1,'B');
			strcat(power,a);
		}
		fclose(fp);
		power[127]='\0';
//		printf("$power = \n%s\n",power);

		
	}
	#endif //armel
	
	// time & load
	
	{
	char uptime[48],time[32],load[32];
	
	system("w > /tmp/w.foo");
	fp = fopen("/tmp/w.foo","r");
	if(fp == NULL){
		snprintf(load,32,"Load: ???");
		snprintf(time,32,"??:??:??");
	}else{
		char temp00[256];
		char *a,*b;
		
		if(fgets(temp00,128,fp)==NULL){
			fclose(fp);
			snprintf(load,32,"Load: ???");
			snprintf(time,32,"??:??:??");	
		}else{
			fclose(fp);
			temp00[255]='\0';

			a = strchr(temp00,'u');
			*a='\0';
			snprintf(time,32,"%s",temp00);

			b=strstr(a+1,"load");
			a=strchr(b,':');
			snprintf(load,32,"Load%s",a);
		}
	}	
	
	system("cat /proc/uptime > /tmp/uptime.foo");
	fp = fopen("/tmp/uptime.foo","r");
	if(fp == NULL){
		snprintf(uptime,32,"Uptime: ???");
	}else{
		char temp00[128];
		float up;	
		int hours,min,sec;	
		
		if(fgets(temp00,128,fp) == NULL){
			fclose(fp);
			snprintf(uptime,32,"Uptime: ???");	
		}else{
			fclose(fp);
			temp00[127]='\0';

			sscanf(temp00,"%f",&up);
		
			hours = up / 3600;
			min = up / 60 - hours*60;
			sec = up - min*60 - hours*3600;

			snprintf(uptime,48,"Uptime: %d:%d:%d",hours,min,sec);
		}
	}
	
		snprintf(load0,128,"%s %s  %s",time,uptime,load);
	}
	

	// memory
	
	system("grep MemFree /proc/meminfo > /tmp/free.foo");
	system("grep Cached /proc/meminfo |grep -v Swap >> /tmp/free.foo");
	fp = fopen("/tmp/free.foo","r");
	if(fp == NULL){
		snprintf(memory,128,"Memory status unavailable");
	}else{
		char temp1[128],temp2[128],*a,*aa;

		if(fgets(temp1,128,fp) == NULL){
			fclose(fp);
			snprintf(memory,128,"Memory status unavailable");
		
		}else{
			if(fgets(temp2,128,fp) == NULL){
				fclose(fp);
				snprintf(memory,128,"Memory status unavailable");			
			}else{
				fclose(fp);
				temp1[127]='\0';
				temp2[127]='\0';

				a = strchr(temp1,'\n');
				*(a) = '\0';

				a = strchr(temp1,':');
				*(a+1) = '\0';

				a = strchr(a+2,' ');
				while(*(a+1) == ' '){
					a++;
				}
			
				aa = strchr(temp2,':');
				*(aa+1) = '\0';

				aa = strchr(aa+2,' ');
				while(*(aa+1) == ' '){
					aa++;
				}
		
				snprintf(memory,128,"%s%s   %s%s",temp1,a,temp2,aa);
			}
		}
					
	}
	
	
	// USB network
	
	i =system("grep usb /proc/net/dev >/dev/null");
	if(i>0){
		snprintf(net1,128," usbnet offline\n");
	}else{
		char temp1[128],*a;

		system("/sbin/ifconfig usb| grep inet > /tmp/usb.foo");
		fp = fopen("/tmp/usb.foo","r");
		if(fp == NULL){
			snprintf(net1,128," usbnet status unavailable\n");
		}else{
			if(fgets(temp1,128,fp) == NULL){
				fclose(fp);
				snprintf(net1,128," usbnet status unavailable\n");
						
			}else{
				fclose(fp);
				temp1[127]='\0';
	
				a = strchr(temp1,'B');
				if(a == NULL){
					snprintf(net1,128," usbnet status unavailable\n");
				}else{
					*a = '\n';
					*(a+1) = '\0';
					a = strchr(temp1,':');
	
					snprintf(net1,128,"%s",a+1);
				}
			}
			
			
		}
	}
	
	
	// 802.11 network
	
	i =system("grep wlan0 /proc/net/dev >/dev/null");
	if(i>0){
		snprintf(net3,128," wlan offline\n");
	}else{
		char temp1[128],*a;

		system("/sbin/ifconfig wlan| grep inet > /tmp/usb.foo");
		fp = fopen("/tmp/usb.foo","r");
		if(fp == NULL){
			snprintf(net3,128," wlan status unavailable\n");
		}else{
			if(fgets(temp1,128,fp) == NULL){
				fclose(fp);
				snprintf(net3,128," wlan status unavailable\n");
			}else{
				fclose(fp);
				temp1[127]='\0';
	
				a = strchr(temp1,'B');
				if(a == NULL){
					snprintf(net3,128," wlan status unavailable\n");
				}else{
					*a = '\n';
					*(a+1) = '\0';
					a = strchr(temp1,':');
	
					snprintf(net3,128,"%s",a+1);
				}
			}
		}
	}
	
	
	// cellular network
	
	i =system("grep ppp /proc/net/dev >/dev/null");
	if(i>0){
			snprintf(net2,128," modem offline\n");
	}else{
		char temp1[128],*a;

		system("/sbin/ifconfig ppp| grep inet > /tmp/ppp.foo");
		fp = fopen("/tmp/ppp.foo","r");
		if(fp == NULL){
			snprintf(net2,128," modem status unavailable\n");
		}else{
			if(fgets(temp1,128,fp) == NULL){
				fclose(fp);
				snprintf(net2,128," modem status unavailable\n");
			}else{
				fclose(fp);
				temp1[127]='\0';

				a = strchr(temp1,'P');
				if(a == NULL){
					snprintf(net2,128," modem status unavailable\n");
				}else{
					*a = '\n';
					*(a+1) = '\0';
					a = strchr(temp1,':');

					snprintf(net2,128,"%s",a+1);
				}
			}
		}
	}
	
	
	snprintf(temp,512,
			"Nomad Status:\n"
			"  %s"
			"  %s"
			"  %s"
			"  usb0: %s"
			"  wlan0: %s"
			"  ppp0: %s"
			,power
			,load0
			,memory
			,net1
			,net3
			,net2);
	
	gtk_label_set_text(GTK_LABEL(text),temp);

	return(TRUE);
}


/******************************************************************************
*
*  makeEngTab()
*/
/** 
*
* @brief
*
****************************************************************/
static void makeEngTab(
		GtkWidget *nb
		,GtkTooltips *tt
		,TXTHNDL *th)
{
	GtkWidget *vb,*hb,*notebook;
	STATUS s;

	s = status_InitStatus();
	

	vb = guiutil_new_tab_with_vbox(nb,"Engineering");
	gtk_widget_show(vb);			 

	notebook=gtk_notebook_new();
	gtk_widget_show(notebook);			 
	gtk_box_pack_start(GTK_BOX(vb),notebook,FALSE,FALSE,0);

	vb = guiutil_new_tab_with_vbox(notebook,"Basic");
	gtk_widget_show(vb);			 
	hb = guiutil_new_frame_with_hbox(vb,"Engineering Telemetry");
	th->EngText[0] = gtk_label_new("Hello!\nHi\nTest");
	gtk_container_add (GTK_CONTAINER (hb), th->EngText[0]);
	gtk_widget_show(th->EngText[0]);

	vb = guiutil_new_tab_with_vbox(notebook,"Extended");
	gtk_widget_show(vb);			 
	hb = guiutil_new_frame_with_hbox(vb,"Engineering Telemetry");
	th->EngText[1] = gtk_label_new("Hello!\nHi\nTest");
	gtk_container_add (GTK_CONTAINER (hb), th->EngText[1]);
	gtk_widget_show(th->EngText[1]);

	setEngineeringText(s,th);
	
	return;

}


/****************************************************************
*
*  makeSciTab()
*/
/** 
*
* @brief
****************************************************************/
void makeSciTab(
		GtkWidget *nb
		,GtkTooltips *tt
		,TXTHNDL *th)
{
	GtkWidget *vb,*hb,*notebook;
	STATUS s;

	s = status_InitStatus();
	
	vb = guiutil_new_tab_with_vbox(nb,"Science");
	gtk_widget_show(vb);			 

	notebook=gtk_notebook_new();	
	gtk_widget_show(notebook);			 
	gtk_box_pack_start(GTK_BOX(vb),notebook,FALSE,FALSE,0);


	vb = guiutil_new_tab_with_vbox(notebook,"  A  ");
	gtk_widget_show(vb);			 

	hb = guiutil_new_frame_with_hbox(vb,"Science Telemetry");
	gtk_widget_show(hb);			 

	th->SciText[0] = gtk_label_new("Hello!\nHi\nTest");	
	gtk_container_add (GTK_CONTAINER (hb), th->SciText[0]);
	gtk_widget_show(th->SciText[0]);
	


	vb = guiutil_new_tab_with_vbox(notebook,"  B  ");
	gtk_widget_show(vb);			 

	hb = guiutil_new_frame_with_hbox(vb,"Science Telemetry");
	gtk_widget_show(vb);			 

	th->SciText[1] = gtk_label_new("Hello!\nHi\nTest");
	gtk_container_add (GTK_CONTAINER (hb), th->SciText[1]);
	gtk_widget_show(th->SciText[1]);
	
	setScienceText(s,th);	

	return;
}


/****************************************************************
*
*  makeCmdTab()
*/
/** 
*
* @brief
*   tab that displays the current COMMAND
*
****************************************************************/
#ifdef PLAT_GUI
static void makeCmdReportTab(
		GtkWidget *nb
		,GtkTooltips *tt
		,TXTHNDL *th)
{
	GtkWidget *vb,*hb;
	COMMAND cmd;

	vb = guiutil_new_tab_with_vbox(nb,"Command");

	hb = guiutil_new_frame_with_hbox(vb,"Current Command");

	cmd = command_InitCommand();
	
	th->CmdText = gtk_label_new("Hello!\nHi\nTest");
	
	setCommandText(cmd,th->CmdText);
	
	gtk_container_add (GTK_CONTAINER (hb), th->CmdText);
	gtk_widget_show(th->CmdText);

	
	return;

}
#endif


/****************************************************************
*
*  makeNomadTab()
*/
/** 
*
* @brief
****************************************************************/
void makeNomadTab(
		GtkWidget *window
		,GtkWidget *nb
		,GtkTooltips *tt
		,TXTHNDL *th)
{
	static GtkWidget *button,*vbox2,*hbox;
//	static SPIN spin_backlight; 


	vbox2 = guiutil_new_tab_with_vbox(nb,"Nomad");
	gtk_widget_show(vbox2);			 


#ifdef PLAT_GUI
{		
	// platform program status and reset button
	
	static GtkWidget *text,*button;

	hbox = guiutil_new_frame_with_hbox(vbox2,"Platform program");

	text = gtk_label_new("");
//	gtk_widget_modify_font (GTK_WIDGET(text),pango_font_description_from_string(TEXTFONT));
	
	callback_platformtext(text);
	gtk_container_add (GTK_CONTAINER (hbox), text);
	gtk_widget_show(text);

	g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,1
			,(GSourceFunc)callback_platformtext,text,NULL);

	button = guiutil_makebutton(hbox, "Start", "Starts platform controller"
				, GTK_SIGNAL_FUNC(callback_platform_start), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

	button = guiutil_makebutton(hbox, "Kill", "Kills platform controller"
				, GTK_SIGNAL_FUNC(callback_platform_kill), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);


}
#endif
{		
	// reboot/shutdown buttons

	hbox = guiutil_new_frame_with_hbox(vbox2,"Shutdown");

	button = guiutil_makebutton(hbox, "Shutdown", "shutdown nomad"
				, GTK_SIGNAL_FUNC(callback_shutdown), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

	button = guiutil_makebutton(hbox, "Reboot", "reboot nomad"
				, GTK_SIGNAL_FUNC(callback_reboot), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);


}
{
	// backlight control
	
	static GtkWidget *button;
	static SPIN spin_backlight; 
	
	hbox = guiutil_new_frame_with_hbox(vbox2,"Backlight");

	spin_backlight = guiutil_make_spinbutton(hbox,"Backlight"
				,DEFAULT_BRIGHTNESS
				,0,255,1,1,0,tt, "Set backlight level");
	gtk_widget_set_size_request((GtkWidget *)(spin_backlight.button), 50, 30);
 
	button = guiutil_makebutton(hbox, "Backlight", "Toggle backlight power"
				, GTK_SIGNAL_FUNC(callback_backlight_toggle), tt, (spin_backlight.button));
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);


#ifdef PLAT_GUI
	button = guiutil_makebutton(hbox, "Blink", "Toggle backlight blink"
				, GTK_SIGNAL_FUNC(callback_backlight_blinktoggle), tt, (spin_backlight.button));
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);
#endif

}
{		
	// set time button

	hbox = guiutil_new_frame_with_hbox(vbox2,"Clock");

	button = guiutil_makebutton(hbox, "Set time", "set time"
				, GTK_SIGNAL_FUNC(callback_settime), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);


}

	return;
}


/****************************************************************
*
*  makeNetworkTab()
*/
/** 
*
* @brief
****************************************************************/
static void makeNetworkTab(
		GtkWidget *window
		,GtkWidget *nb
		,GtkTooltips *tt
		,TXTHNDL *th)
{
	static GtkWidget *text,*button,*vbox2,*hbox;



	vbox2 = guiutil_new_tab_with_vbox(nb,"Network");
	gtk_widget_show(vbox2);			 

{		
	// ppp program status and controls
	
	hbox = guiutil_new_frame_with_hbox(vbox2,"Modem");
//	hbox =util_new_hbox(vbox2);

	text = gtk_label_new("");
//	gtk_widget_modify_font (GTK_WIDGET(text)
//		,pango_font_description_from_string(TEXTFONT));
	
	callback_pppstatustext(text);
	gtk_container_add (GTK_CONTAINER (hbox), text);
	gtk_widget_show(text);

	g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,1
			,(GSourceFunc)callback_pppstatustext,text,NULL);

	button = guiutil_makebutton(hbox, "Connect", "dial modem"
				, GTK_SIGNAL_FUNC(callback_cellmodem_dial), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

	button = guiutil_makebutton(hbox, "Hangup", "hangup modem"
				, GTK_SIGNAL_FUNC(callback_cellmodem_hangup), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);


	// set / remove route for USB network
	
	hbox = guiutil_new_frame_with_hbox(vbox2,"USBnet");

	button = guiutil_makebutton(hbox, "Route", "make usb route"
				, GTK_SIGNAL_FUNC(callback_usbnet_route), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

	button = guiutil_makebutton(hbox, "De-route", "remove usb route"
				, GTK_SIGNAL_FUNC(callback_usbnet_unroute), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);


	// change wireless network
	
	hbox = guiutil_new_frame_with_hbox(vbox2,"802.11");

	button = guiutil_makebutton(hbox, "Home", "set home essid"
				, GTK_SIGNAL_FUNC(callback_wlan_sethomeessid), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

	button = guiutil_makebutton(hbox, "CMU", "set CMU essid"
				, GTK_SIGNAL_FUNC(callback_wlan_setcmuessid), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

	button = guiutil_makebutton(hbox, "Pump", "get IP address"
				, GTK_SIGNAL_FUNC(callback_wlan_pump), tt, window);
	gtk_widget_set_size_request((GtkWidget *)(button), 100, 60);

}

	return;
}


/******************************************************************************
*
*  makeMainTabs()
*/
/** 
*
* @brief
****************************************************************/
static void makeMainTabs(
		GtkWidget *window
		,GtkWidget *nb
		,CONFIGDATA cf)
{
	static TXTHNDL th;	
	GtkTooltips *tt;//tooltips

	tt = gtk_tooltips_new();

	// engineering tab
	makeEngTab(nb,tt,&th);

	// science tab
	makeSciTab(nb,tt,&th);


#ifdef PLAT_GUI
	snprintf(telemfilespec,sizeof(telemfilespec),
		"%s/%s%d.%s",cf.localdatapath,cf.telemfilebase
		,cf.robotnumber,cf.telemfileext);

	snprintf(cmdfilespec,sizeof(cmdfilespec),
		"%s/%s%d.%s",cf.localdatapath,cf.cmdfilebase
		,cf.robotnumber,cf.cmdfileext);

	// command tab
	makeCmdReportTab(nb,tt,&th);

	// set timeout for updating engineering and science tabs
	g_timeout_add_full(G_PRIORITY_DEFAULT,250
			,(GSourceFunc)callback_telem_cmd_localfiles,&th,NULL);
#endif

#ifdef CONTROLLER
	// Command tab
	makeCmdBuilderTab(window,nb,tt,&th,cf);

	if(cf.usenetwork == 1){
		// set timeout for updating engineering and science tabs
		g_timeout_add_full(G_PRIORITY_DEFAULT,250
				,(GSourceFunc)callback_telem_remotefile,&th,NULL);
	}		
#endif


	// Nomad tab
	makeNomadTab(window,nb,tt,&th);

	// Network tab
	makeNetworkTab(window,nb,tt,&th);


	return;
}


/****************************************************************
*
*	help_callback()
*
*
****************************************************************/
static void help_callback(
		GtkWidget *widget
		, gpointer   data )
{
	GtkWidget *window;
	
	window = (GtkWidget *)data;

//	WINDATA *wd;
	
//	wd = (WINDATA *)data;
   
//	help_dialog(GTK_WINDOW(wd->win),gtk_notebook_get_current_page(GTK_NOTEBOOK(wd->nb)));
	
	return;
}


/****************************************************************
*
*	make_menu()
*
*
****************************************************************/
GtkWidget *make_menu(
		GtkWidget *window)
{
	GtkWidget *menubar,*menuitem,*menu,*menuFile,*menuHelp;
	GtkWidget *vbox;

	vbox=gtk_vbox_new(FALSE,0);
	gtk_container_add (GTK_CONTAINER (window), vbox);
	gtk_widget_show(vbox);			 

	menubar=gtk_menu_bar_new();
	gtk_widget_show(menubar);			 
	
// file menu

	menuFile = gtk_menu_item_new_with_label("File");
	gtk_menu_append(GTK_MENU_BAR(menubar), menuFile);
	gtk_widget_show (menuFile);
	
	menu=gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuFile),menu);
	
	menuitem = gtk_menu_item_new_with_label ("Exit");
	gtk_menu_append(GTK_MENU(menu), menuitem);
	gtk_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC (destroy), NULL);
	gtk_widget_show (menuitem);


//	help menu

	menuHelp = gtk_menu_item_new_with_label("Help");
	gtk_menu_append(GTK_MENU_BAR(menubar), menuHelp);
	gtk_menu_item_right_justify(GTK_MENU_ITEM(menuHelp));
	gtk_widget_show (menuHelp);

	menu=gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuHelp),menu);

	menuitem = gtk_menu_item_new_with_label ("Help");
	gtk_menu_append(GTK_MENU(menu), menuitem);
	gtk_signal_connect(GTK_OBJECT (menuitem), "activate"
			, GTK_SIGNAL_FUNC (help_callback), window);
	gtk_widget_show (menuitem);

	gtk_box_pack_start(GTK_BOX(vbox),menubar,FALSE,FALSE,0);

	return(vbox);
}


/******************************************************************************
*
*	make_status()
*/
/** 
*
* @brief
*
****************************************************************/
static void make_status(
		GtkWidget *vbox)
{
	static GtkWidget *text;
	GtkWidget *hbox;
		
	hbox = guiutil_new_hbox(vbox);

	text = gtk_label_new("");
	
	callback_status(text);
	
	gtk_container_add (GTK_CONTAINER (hbox), text);
	gtk_widget_show(text);

	g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,1
			,(GSourceFunc)callback_status,text,NULL);
	
	return;
}


/******************************************************************************
*
*	make_notebook()
*/
/** 
*
* @brief
*
****************************************************************/
GtkWidget * make_notebook(
		GtkWidget *window
		,GtkWidget *vbox
		,CONFIGDATA cf)
{
	GtkTooltips *tt;	// tooltips for the buttons in this tab
	GtkWidget *nb;

	tt = gtk_tooltips_new();

	// area at top contains notebook tabs
	nb=gtk_notebook_new();
	gtk_widget_show(nb);			 
	
	gtk_box_pack_start(GTK_BOX(vbox),nb,FALSE,FALSE,0);

	makeMainTabs(window,nb,cf);
	

	// area at bottom contains local system status
	make_status(vbox);
	

	return(nb);
}


/****************************************************************
*
*	make_mainwin()
*
*
****************************************************************/
GtkWidget *make_mainwin(
		int width
		,int height)
{
	GtkWidget *window;
	
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	
	gtk_widget_set_size_request((GtkWidget *)(window), width, height);
	
	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);   
	
	gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                        GTK_SIGNAL_FUNC (delete_event), NULL);
								
	gtk_signal_connect (GTK_OBJECT (window), "destroy",
                        GTK_SIGNAL_FUNC (destroy), NULL);
    
	gtk_container_set_border_width (GTK_CONTAINER (window), 5);
	
	return(window);
}



